// ============================================================================
//
// Copyright (C) 2006-2007 Dengues
//
// Google Group: http://groups.google.com/group/dengues
// QQ Group: 24885404
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ============================================================================
package org.dengues.commons.ui.swt.table;

import org.dengues.commons.IDenguesSharedImage;
import org.dengues.commons.utils.ImageUtil;
import org.eclipse.jface.bindings.keys.KeyStroke;
import org.eclipse.jface.bindings.keys.ParseException;
import org.eclipse.jface.fieldassist.ContentProposalAdapter;
import org.eclipse.jface.fieldassist.IContentProposalProvider;
import org.eclipse.jface.fieldassist.IControlContentAdapter;
import org.eclipse.jface.fieldassist.SimpleContentProposalProvider;
import org.eclipse.jface.fieldassist.TextContentAdapter;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;

/**
 * Qiang.Zhang.Adolf@gmail.com class global comment. Detailled comment <br/>
 * 
 */
public abstract class AbstractTableViewer extends Composite {

    public static String PROP_KEY = "PROP_KEY"; //$NON-NLS-1$

    public static String PROP_NAME = "PROP_NAME"; //$NON-NLS-1$

    public static String PROP_DBTYPE = "PROP_DBTYPE"; //$NON-NLS-1$

    public static String PROP_NULLABLE = "PROP_NULLABLE"; //$NON-NLS-1$

    public static String PROP_LENGTH = "PROP_LENGTH"; //$NON-NLS-1$

    public static String PROP_PATTERN = "PROP_PATTERN"; //$NON-NLS-1$

    public static String PROP_PRECISION = "PROP_PRECISION"; //$NON-NLS-1$

    public static String PROP_DEFAULT = "PROP_DEFAULT"; //$NON-NLS-1$

    public static String PROP_COMMENT = "PROP_COMMENT"; //$NON-NLS-1$

    protected Label title;

    protected TableViewer tableViewer;

    protected Table table;

    public static final int DEFAULT_COLUMN_WITH = 60;

    public static final int FIRST_COLUMN_WITH = 23;

    public static final String SPACES = "SPACES"; //$NON-NLS-1$

    private SelectionListener addListener;

    private static String[] PATTERNS = new String[] { "yyyy-MM-dd HH:mm:ss", "yyyy.MM.dd G 'at' HH:mm:ss z", //$NON-NLS-1$ //$NON-NLS-2$
            "yyyyy.MMMMM.dd GGG hh:mm aaa", "yyyy-MM-dd'T'HH:mm:ss.SSSZ" }; //$NON-NLS-1$ //$NON-NLS-2$

    /**
     * Qiang.Zhang.Adolf@gmail.com AbstactTableViewer constructor comment.
     * 
     * @param parent
     * @param style
     */
    public AbstractTableViewer(Composite parent, boolean isReadOnly) {
        super(parent, SWT.NONE);
        GridLayout gridLayout = new GridLayout();
        gridLayout.marginBottom = 0;
        gridLayout.marginHeight = 0;
        gridLayout.marginLeft = 0;
        gridLayout.marginRight = 0;
        gridLayout.marginTop = 0;
        gridLayout.marginWidth = 0;
        gridLayout.verticalSpacing = 0;
        setLayout(gridLayout);
        GridData gridData = new GridData(GridData.FILL_BOTH);
        setLayoutData(gridData);
        setBackground(parent.getBackground());
        title = new Label(this, SWT.NONE);
        title.setBackground(getBackground());
        gridData = new GridData(GridData.FILL_HORIZONTAL);
        gridData.heightHint = 12;
        title.setLayoutData(gridData);
        initTable();
        if (!isReadOnly) {
            initToolBar();
        }
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "initTable".
     */
    protected void initTable() {
        tableViewer = new TableViewer(this, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.FULL_SELECTION);
        table = tableViewer.getTable();
        table.setHeaderVisible(true);
        table.setLinesVisible(true);
        GridData data = new GridData(GridData.FILL_BOTH);
        data.heightHint = 100;
        table.setLayoutData(data);
        attachProvider();
        addColumns();
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "initTableInput".
     */
    public void initTableInput() {
        attachCellEidtor();
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "addColumns".
     */
    public void addColumns() {
        TableColumn column = new TableColumn(table, SWT.NONE);
        column.setWidth(FIRST_COLUMN_WITH);
        column.setText(""); //$NON-NLS-1$
        column.setResizable(false);
        column.setMoveable(false);
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "attachCellEidtor".
     */
    public abstract void attachCellEidtor();

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "attachProvider".
     */
    public abstract void attachProvider();

    protected void initToolBar() {
        Composite toolBar = new Composite(this, SWT.NONE);
        GridLayout gridLayout = new GridLayout(2, false);
        gridLayout.marginBottom = 0;
        gridLayout.marginHeight = 0;
        gridLayout.marginLeft = 0;
        gridLayout.marginRight = 0;
        gridLayout.marginTop = 0;
        gridLayout.marginWidth = 0;
        toolBar.setLayout(gridLayout);
        GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
        gridData.heightHint = 25;
        toolBar.setLayoutData(gridData);
        toolBar.setBackground(this.getBackground());
        Button button = new Button(toolBar, SWT.PUSH);
        button.setImage(ImageUtil.getImage(IDenguesSharedImage.ACTION_TOOLBAR_ADD));
        addListener = configAddButtonListener();
        button.addSelectionListener(addListener);
        button = new Button(toolBar, SWT.PUSH);
        button.setImage(PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_TOOL_DELETE));
        button.addSelectionListener(configRemoveButtonListener());
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "configAddButtonListener".
     * 
     * @return
     */
    public abstract SelectionListener configAddButtonListener();

    public abstract SelectionListener configRemoveButtonListener();

    public void setTitle(String title) {
        this.title.setText(title);
    }

    /**
     * Getter for tableViewer.
     * 
     * @return the tableViewer
     */
    public TableViewer getTableViewer() {
        return this.tableViewer;
    }

    protected void installPatternProposal(Control text) {
        try {
            KeyStroke keyStroke = KeyStroke.getInstance("Alt+.");//$NON-NLS-1$
            IControlContentAdapter contentAdapter = new TextContentAdapter();
            IContentProposalProvider provider = new SimpleContentProposalProvider(PATTERNS);
            ContentProposalAdapter adapter = new ContentProposalAdapter(text, contentAdapter, provider, keyStroke, new char[] {});
            adapter.setPropagateKeys(true);
            adapter.setFilterStyle(ContentProposalAdapter.FILTER_CUMULATIVE);
            adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
            adapter.setPopupSize(new Point(300, 200));
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}
